﻿using System.Collections.Generic;
using System.Web.Mvc;
using Nop.Plugin.Nova.Janrain.Models;
using Nop.Services.Configuration;
using Nop.Services.Payments;
using Nop.Web.Framework.Controllers;
using Nop.Plugin.Nova.Janrain.Service;
using System.Xml;
using Nop.Core.Domain.Customers;
using Nop.Services.Customers;
using System;
using Nop.Services.Authentication;
using System.Web.Security;
using Nop.Core;

namespace Nop.Plugin.Nova.Janrain.Controllers
{
    public class NovaJanrainController : Controller
    {
        private readonly ISettingService _settingService;
        private readonly NovaJanrainSettings _adSettings;
        private readonly ICustomerService _customerService;
        private readonly IAuthenticationService _authenticationService;
        private readonly IWorkContext _workContext;
        private readonly ICustomerRegistrationService _customerRegistrationService;

        private IJanrainEngageService _janrainEngageService
        {
            get
            {
                return new JanrainEngageService();
            }
        }

        public NovaJanrainController(ISettingService settingService, NovaJanrainSettings adSettings, ICustomerService customerService, IAuthenticationService authenticationService, IWorkContext workContext, ICustomerRegistrationService customerRegistrationService)
        {
            this._settingService = settingService;
            this._adSettings = adSettings;
            this._customerService = customerService;
            this._authenticationService = authenticationService;
            this._workContext = workContext;
            this._customerRegistrationService = customerRegistrationService;
        }
        
        [AdminAuthorize]
        [ChildActionOnly]
        public ActionResult Configure()
        {
            var model = new ConfigurationModel();
            model.StoreUrl = _adSettings.StoreUrl;
            model.IsEnable = _adSettings.IsEnable;
            model.ReturnUrl = _adSettings.ReturnUrl;
            model.ApiKey = _adSettings.ApiKey;

            return View("Nop.Plugin.Nova.Janrain.Views.NovaJanrain.Configure", model);
        }

        [HttpPost]
        [AdminAuthorize]
        [ChildActionOnly]
        public ActionResult Configure(ConfigurationModel model)
        {
            if (!ModelState.IsValid)
                return Configure();
            
            //save settings
            _adSettings.StoreUrl = model.StoreUrl;
            _adSettings.IsEnable = model.IsEnable;
            _adSettings.ReturnUrl = model.ReturnUrl;
            _adSettings.ApiKey = model.ApiKey;
            _settingService.SaveSetting(_adSettings);
            
            return View("Nop.Plugin.Nova.Janrain.Views.NovaJanrain.Configure", model);
        }

        [ChildActionOnly]
        public ActionResult JanrainInfo()
        {
            var model = new JanrainModel()
            {
                StoreUrl = _adSettings.StoreUrl,
                ReturnUrl = _adSettings.ReturnUrl,
                IsEnable = _adSettings.IsEnable,
                ApiKey = _adSettings.ApiKey,
            };

            return View("Nop.Plugin.Nova.Janrain.Views.NovaJanrain.JanrainInfo", model);
        }

        public ActionResult JanrainProcess(string token)
        {
            var apiKey = _adSettings.ApiKey;

            string parameters = "token=" + token + "&apiKey=" + apiKey + "&format=xml&extended=true";
            string uri = "https://rpxnow.com/api/v2/" + "auth_info";

            XmlDocument xmldocument = _janrainEngageService.GetJanrainEngageInfo(parameters, uri);

            //for testing
            //string parameters1 = "token=" + tokenValue + "&apiKey=" + apiKey + "&format=xml&extended=true";
            //string uri = "https://rpxnow.com/api/v2/" + "auth_info";

            //XmlDocument xmldocument = localEngageService.GetJanrainEngageInfo(parameters, uri);
            //testing end

            if (xmldocument == null)
            {
                return RedirectToRoute("login");
            }
            var user = new JanrainEngageUser(xmldocument.DocumentElement);
            if (user == null)
            {
                return RedirectToRoute("login");
            }

            //Insert data into Nop.Customer table
            Customer customer = new Customer();
            var userName = user.Email;
            if (string.IsNullOrEmpty(user.Email))
            {
                customer = _customerService.GetCustomerByEmail(user.UserName.ToLower().Replace(" ", "") + "@hotmail.com");
            }
            else
            {
                customer = _customerService.GetCustomerByEmail(userName);
            }

            if (customer == null)
            {
                customer = _workContext.CurrentCustomer;
                if (string.IsNullOrEmpty(user.Email))
                {
                    user.Email = user.UserName.ToLower().Replace(" ", "") + "@hotmail.com";
                }
                _authenticationService.SignOut();
                var registrationRequest = new CustomerRegistrationRequest(customer, user.Email,
                    user.Email, "123456", PasswordFormat.Hashed, true);
                var registrationResult = _customerRegistrationService.RegisterCustomer(registrationRequest);

            }

            _authenticationService.SignIn(customer, true);
            //FormsAuthentication.SetAuthCookie(customer.Username, false);
            return Redirect(_adSettings.ReturnUrl);

            //return RedirectToRoute("login");
            
        }

        public string GetRandomPasswordUsingGUID(int length)
        {
            // Get the GUID
            string guidResult = System.Guid.NewGuid().ToString();
            // Remove the hyphens
            guidResult = guidResult.Replace("-", string.Empty);
            // Make sure length is valid
            if (length <= 0 || length > guidResult.Length)
                throw new ArgumentException("Length must be between 1 and " + guidResult.Length);
            // Return the first length bytes
            return guidResult.Substring(0, length);
        }
    }
}